﻿//-----------------------------------------------------------------------
// <copyright company="www.3WayWebdesign.de">
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
//
// <author>Michael Morbach</author>
// <email>Michael@3waywebdesign.de</email>
// <web>http://www.3waywebdesign.de</web>
//-----------------------------------------------------------------------

namespace Tww.MAF.MAFInfrastructure.Models.Base
{
    #region Imports

    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;
    using Microsoft.Practices.Unity;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Tww.MAF.MAFInfrastructure.Events.Args;
    using Tww.MAF.MAFInfrastructure.Interfaces.ViewModels;
    using Tww.MAF.MAFInfrastructure.Interfaces.Views;


    #endregion

    public class ContentViewModelBase : ViewModelBase, IContentViewModel
    {
        #region Private Fields

        /** Commands **/
        private RelayCommand closeCommand;
        private RelayCommand showHelpCommand;
        private RelayCommand refreshContentCommand;
        private RelayCommand saveContentCommand;

        private string title = string.Empty;
        private bool isContentLoading = false;

        #endregion

        #region Ctors

        protected ContentViewModelBase( IUnityContainer unityContainer, string title )
        {
            this.UnityContainer = unityContainer;
            this.Title = title;
            this.UIScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        }

        #endregion

        #region Public Properties

        public bool IsContentLoading
        {
            get { return this.isContentLoading; }
            protected set
            {
                this.isContentLoading = value;
                this.RaisePropertyChanged<bool>( () => IsContentLoading );
            }
        }

        public bool IsCleanedup
        {
            get;
            private set;
        }

        public virtual string Title
        {
            get { return title; }
            set
            {
                title = value;
                this.RaisePropertyChanged<string>( () => Title );
            }
        }

        public bool CanCloseProperty
        {
            get { return this.CanClose(); }
        }

        public bool CanSaveProperty
        {
            get { return CanSaveContent(); }
        }

        public bool CanRefreshProperty
        {
            get { return this.CanRefreshContent(); }
        }

        public bool CanShowHelpProperty
        {
            get { return this.CanShowHelp(); }
        }

        #endregion

        #region Private Properties

        protected IUnityContainer UnityContainer { get; set; }

        protected TaskScheduler UIScheduler { get; private set; }

        #endregion

        #region Public Methods

        public override void Cleanup()
        {
            if ( !this.IsCleanedup )
            {
                this.UIScheduler = null;
                this.UnityContainer = null;
                base.Cleanup();
                this.IsCleanedup = true;
            }
        }

        public virtual bool CanClose()
        {
            return true;
        }

        public virtual void Close()
        {
            var closeHandler = this.RequestCloseContentPresenter;

            if ( closeHandler != null )
            {
                closeHandler( this, EventArgs.Empty );
            }
        }

        public void NavigateTo( IContentView nextContent )
        {
            var navigationHandler = this.RequestNavigateTo;

            if ( navigationHandler != null )
            {
                navigationHandler( this, new ContentNavigationEventArgs( nextContent ) );
            }
        }

        public void NavigateBack()
        {
            var navigationHandler = this.RequestNavigateBack;

            if ( navigationHandler != null )
            {
                navigationHandler( this, EventArgs.Empty );
            }
        }

        public virtual void OnPresenterIsNavigatingTo( IContentView nextContent, ref bool cancelNavigation )
        {
        }

        public virtual void OnPresenterIsNavigatingBack( IContentView previousContent, ref bool cancelNavigation )
        {
        }

        public virtual void OnPresenterIsNavigatingFrom( IContentView navigatingFrom, ref bool cancelNavigation )
        {
        }

        #endregion

        #region Commands

        public System.Windows.Input.ICommand CloseContentCommand
        {
            get
            {
                if ( this.closeCommand == null )
                {
                    this.closeCommand = new RelayCommand( () => this.Close(), () => this.CanClose() );
                }

                return this.closeCommand;
            }
        }

        public System.Windows.Input.ICommand SaveContentCommand
        {
            get
            {
                if ( this.saveContentCommand == null )
                {
                    this.saveContentCommand = new RelayCommand( () => this.SaveContent(), () => this.CanSaveContent() );
                }

                return this.saveContentCommand;
            }
        }

        public System.Windows.Input.ICommand RefreshContentCommand
        {
            get
            {
                if ( this.refreshContentCommand == null )
                {
                    this.refreshContentCommand = new RelayCommand( () => this.RefreshContent(), () => this.CanRefreshContent() );
                }

                return this.refreshContentCommand;
            }
        }

        public System.Windows.Input.ICommand ShowHelpCommand
        {
            get
            {
                if ( this.showHelpCommand == null )
                {
                    this.showHelpCommand = new RelayCommand( () => this.ShowHelp(), () => this.CanShowHelp() );
                }

                return this.showHelpCommand;
            }
        }

        #endregion

        #region Events

        public event EventHandler<ContentNavigationEventArgs> RequestNavigateTo;

        public event EventHandler RequestNavigateBack;

        public event EventHandler RequestCloseContentPresenter;

        #endregion

        #region Content Functions

        public virtual bool CanSaveContent()
        {
            return true;
        }

        public virtual void SaveContent()
        {

        }

        public virtual bool CanRefreshContent()
        {
            return true;
        }

        public virtual void RefreshContent()
        {
        }

        public virtual bool CanShowHelp()
        {
            return true;
        }

        public virtual void ShowHelp()
        {
        }

        #endregion
    }
}
